#pragma once

#include <memory>
#include <stdexcept>

#include "rtda/local_vars.h"
#include "rtda/operand_stack.h"
#include "rtda/thread.h"
#include "rtda/heap/method.h"

namespace jvm {
namespace rtda {

// 前向声明
class Thread;
class OperandStack;
class LocalVars;
// class heap::Method;

class Frame{
public:
    Frame(std::weak_ptr<Thread> thread = std::weak_ptr<Thread>(), std::shared_ptr<heap::Method> method = nullptr) 
        : _p_method(method),
          _local_vars(_p_method->getMaxLocals()), 
          _p_operand_stack(std::make_shared<OperandStack>(_p_method->getMaxStack())),
          _p_thread(thread),
          _next_pc(0) {};

    Frame(const Frame&) = delete; // 禁止拷贝构造
    Frame& operator=(const Frame&) = delete; // 禁止赋值操作
    Frame(Frame&&) = default; // 允许移动构造
    Frame& operator=(Frame&&) = default; // 允许移动赋值
    ~Frame() = default;

    LocalVars& getLocalVars();

    std::shared_ptr<OperandStack> getOperandStack();

    std::shared_ptr<Thread> getThread();
    void setThread(std::weak_ptr<Thread> thread);
    
    uint32_t getNextPC() const;
    void setNextPC(uint32_t next_pc);

    std::shared_ptr<heap::Method> getMethod() const;
    
private:
    std::shared_ptr<heap::Method> _p_method; // 当前方法
    LocalVars _local_vars;
    std::shared_ptr<OperandStack> _p_operand_stack;
    std::weak_ptr<Thread> _p_thread; // 线程
    uint32_t _next_pc; // 下一条指令的地址
};

} // namespace rtda
} // namespace jvm
